home *** CD-ROM | disk | FTP | other *** search
- ;$Author: DCODY $
- ;$Date: 24 Feb 1993 16:08:32 $
- ;$Header: X:/sccs/fm/3812a.asv 1.8 24 Feb 1993 16:08:32 DCODY $
- ;$Log: X:/sccs/fm/3812a.asv $
- ;
- ; Rev 1.8 24 Feb 1993 16:08:32 DCODY
- ; moved externADDR macros around for Borland...
- ;
- ; Rev 1.7 03 Feb 1993 11:59:32 DCODY
- ; checking splitmode,0 was changed to splitmode,1
- ;
- ; Rev 1.6 08 Dec 1992 16:50:28 DCODY
- ; moved externADDR macro for Borlands link
- ;
- ; Rev 1.5 20 Oct 1992 11:10:42 DCODY
- ; adjusted tiny model .data declaration
- ;
- ; Rev 1.4 24 Sep 1992 08:51:56 DCODY
- ; changed MVGetHardware to mvGetHardware
- ;
- ; Rev 1.3 20 Jul 1992 11:40:56 DCODY
- ; call to mvGetHWVersion requests active I/O detection.
- ;
- ; Rev 1.2 17 Jul 1992 13:55:46 DCODY
- ; base I/O address can now move...
- ;
- ; Rev 1.1 27 Jun 1992 14:47:08 DCODY
- ; fixed FMsplit for the opl3, and outdual3812 now programs one
- ; side of the OPL3 at a time.
- ;
- ; Rev 1.0 26 Jun 1992 14:21:58 BCRANE
- ; Initial revision.
- ;
- ; Rev 1.3 26 Jun 1992 14:12:08 DCODY
- ; added the parameter to the gethwversion call.
- ;
- ; Rev 1.2 25 Jun 1992 21:11:10 DCODY
- ; finished the init routine. Made timing loops variable based
- ; upon the installed FM chip.
- ;
- ; Rev 1.1 23 Jun 1992 16:32:30 DCODY
- ; PAS2 update
- ;
- ; Rev 1.0 15 Jun 1992 09:39:46 BCRANE
- ; Initial revision.
- ;$Logfile: X:/sccs/fm/3812a.asv $
- ;$Modtimes$
- ;$Revision: 1.8 $
-
- Title 3812/OPL3 Access Routines
-
- ; /*\
- ;---|*|---===< 3821A.ASM >====----
- ;---|*|
- ;---|*| This is the output routine to write data to the twin 3821 chips,
- ;---|*| or OPL-3 4OP synth chip.
- ;---|*|
- ;---|*| Media Vision, Inc. Copyright (c) 1991,1992. All Rights Reserved.
- ;---|*|
- ; \*/
-
- .xlist
- include model.inc
- include masm.inc
- include state.inc
- include target.inc
- include common.inc
- .list
-
- if MODELSIZE eq 0
- .code
- else
- .data
- endif
-
- if @codesize
- externADDR mvGetHWVersion
- externADDR MVInitStatePtr
- endif
-
- extrn _MVHWVersionBits :word
- extrn _MVTranslateCode :word
- extrn mvhwShadowPointer :dword
-
- indexwrite dw 05 ; 3812 index write delays
- datawrite dw 35 ; 3812 data write delays
- splitmode db 0 ; 00 = mono, 01 = stereo
-
- .code
-
- ife @codesize
- externADDR mvGetHWVersion
- externADDR MVInitStatePtr
- endif
-
- ;
- ; /*\
- ;---|*|---===< mvFMInitMode (int) >====----
- ;---|*|
- ;---|*| This routine initializes the Dual 3812/OPL-3 chip
- ;---|*|
- ;---|*| Entry Conditions:
- ;---|*| wParm1 = 0 to setup for mono, 1 to setup for sterero
- ;---|*|
- ;---|*| Exit Conditions:
- ;---|*| AX,BX,CX,DX modified
- ;---|*|
- ; \*/
- public mvFMInitMode
- mvFMInitMode proc
- push bp
- mov bp,sp
- ;
- ; validate the hardware if not done already.
- ;
- cmp [_MVHWVersionBits],-1 ; check to see if we know the hardware
- jnz @F
- mov ax,USE_ACTIVE_ADDR
- push ax
- call mvGetHWVersion ; get the hardware version
- add sp,2
- cmp al,-1 ; everything here?
- jz mvmfexit ; no, exit out now...
- ;
- @@:
- ;
- ; validate the state table pointer
- ;
- cmp word ptr [mvhwShadowPointer+2],0
- jnz @F
- call MVInitStatePtr
- ;
- ; setup I/O delays based upon the installed FM chip
- ;
- test [_MVHWVersionBits],bMVOPL3 ; defaults are setup for 3812
- jz @F ; which are okay, exit out now...
- mov [indexwrite],3 ; OPL3 index write delays
- mov [datawrite], 3 ; OPL3 data write delays
- ;
- @@:
- ;
- ; set the chips in mono mode, then flush them.
- ;
- sub ax,ax ; set the chip(s) in mono mode
- mov splitmode,al
- call FMsplit
-
- mov dx,LFMADDR ; flush the left/right side
- xor dx,[_MVTranslateCode] ; translate to the board address
- call flushit
- ;
- ; now, split the chips into stereo mode if requested to do so
- ;
- cmp wptr wParm1,0 ; all done?
- jz mvmfexit ; yes, exit
-
- mov al,1 ; split it now
- mov splitmode,al
- call FMsplit
- ;
- mvmfexit:
- pop bp
- ret
-
- mvFMInitMode endp
-
- ;
- ; /*\
- ;---|*|---===< outdual3812(int,int,int) >====----
- ;---|*|
- ;---|*| This routine writes index/data to
- ;---|*| both chips in an interleaved fashion.
- ;---|*|
- ;---|*| Entry Conditions:
- ;---|*| wParm1 is the chip index value
- ;---|*| wParm2 is the left FM chip data
- ;---|*| wParm3 is the right FM chip data
- ;---|*|
- ;---|*| Exit Conditions:
- ;---|*| AX,DX,CX modified
- ;---|*|
- ; \*/
-
- public outdual3812
- outdual3812 proc
- ;
- ; this is kinda screwy, but if we're in mono mode, don't write to both sides
- ;
- cmp splitmode,1 ; are we doing both?
- jjnz outleft3812 ; no, just do the left side...
- ;
- ; frame the stack and continue.
- ;
- push bp
- mov bp,sp
- ;
- ; write the index to both chips
- ;
- mov dx,LFMADDR ; get the left 3812 address
- xor dx,[_MVTranslateCode] ; translate to the board address
- mov al,wParm1 ; get the index value
- ;
- ; special case the OPL3 since it only really has one index register.
- ;
- test [_MVHWVersionBits],bMVOPL3 ; defaults are setup for 3812
- jnz outtoopl3 ; which are okay, exit out now...
- ;
- ; the dual 3812s can have interleaved I/O to speed up the pace
- ;
- out dx,al ; output to both chips
- add dx,2
- out dx,al
- ;
- ; wait the proper delays for either FM chip
- ;
- mov cx,[indexwrite]
- ;
- @@:
- in al,dx
- loop @B
- ;
- ; write the data out to the chip now
- ;
- dec dx ; move back to the left FM data reg
- mov al,byte ptr wParm2
- mov ah,byte ptr wParm3
-
- out dx,al ; write the data out
- add dx,2
- xchg ah,al
- out dx,al
- ;
- ; wait the proper delays for either FM chip
- ;
- mov cx,[datawrite]
- ;
- @@:
- in al,dx
- loop @B
-
- pop bp
- ret
- ;
- outtoopl3:
- ;
- ; do the left side of the OPL3 first
- ;
- ; write the left index
-
- out dx,al ; output to both chips
- mov cx,[indexwrite]
- ;
- @@:
- in al,dx
- loop @B
-
- ; write the left data
-
- inc dx ; move to the left FM data reg
- mov al,wParm2
- out dx,al ; write the data out
- mov cx,[datawrite]
- ;
- @@:
- in al,dx
- loop @B
- ;
- ; do the right side of the OPL3 next
- ;
- ; write the right index
-
- inc dx
- mov ax,wParm1 ; get the index value
- out dx,al ; output to both chips
- mov cx,[indexwrite]
- ;
- @@:
- in al,dx
- loop @B
-
- ; write the right data
-
- inc dx ; move to the left FM data reg
- mov al,wParm3
-
- out dx,al ; write the data out
- mov cx,[datawrite]
- ;
- @@:
- in al,dx
- loop @B
-
- pop bp
- ret
-
- outdual3812 endp
-
- ;
- ; /*\
- ;---|*|---===< outleft3812(int,int) >====----
- ;---|*|
- ;---|*| This routine writes index/data to the left FM chip.
- ;---|*|
- ;---|*| Entry Conditions:
- ;---|*| wParm1 is the left FM index
- ;---|*| wParm2 is the left FM chip data
- ;---|*|
- ;---|*| Exit Conditions:
- ;---|*| AX,DX,CX modified
- ;---|*|
- ; \*/
-
- public outleft3812
- outleft3812 proc
- push bp
- mov bp,sp
- ;
- ; write the index to both chips
- ;
- mov dx,LFMADDR ; get the left 3812 address
- xor dx,[_MVTranslateCode] ; translate to the board address
- ;
- fm_common_output label near
- ;
- ; output the index to the single chip
- ;
- mov ax,wParm1 ; get the index value
- out dx,al ; output to both chips
- mov cx,[indexwrite]
- ;
- @@:
- in al,dx ; slow down for the index to settle
- loop @B
-
- inc dx ; move to the data register
-
- mov ax,wParm2
- out dx,al ; write the data out
-
- mov cx,[datawrite]
- ;
- @@:
- in al,dx
- loop @B
-
- pop bp
- ret
-
- outleft3812 endp
-
- ;
- ; /*\
- ;---|*|---===< outright3812(int,int) >====----
- ;---|*|
- ;---|*| This routine writes index/data to the right FM chip.
- ;---|*|
- ;---|*| Entry Conditions:
- ;---|*| wParm1 is the right FM index
- ;---|*| wParm1 is the right FM chip data
- ;---|*|
- ;---|*| Exit Conditions:
- ;---|*| AX,DX,CX modified
- ;---|*|
- ; \*/
-
- public outright3812
- outright3812 proc
- push bp
- mov bp,sp
- ;
- ; write the index to both chips
- ;
- mov dx,RFMADDR ; get the right 3812 address
- xor dx,[_MVTranslateCode] ; translate to the board address
- jmp short fm_common_output
-
- outright3812 endp
-
- ;
- ;--------------------------==========================--------------------------
- ;--------------------------====< local routines >====--------------------------
- ;--------------------------==========================--------------------------
- ;
-
- ;
- ; /*\
- ;---|*|---===< flushit >====----
- ;---|*|
- ;---|*| Reset both sides of the FM chip(s)
- ;---|*|
- ;---|*| Entry Conditions:
- ;---|*| none
- ;---|*|
- ;---|*| Exit Conditions:
- ;---|*| AX,BX,CX,DX modified
- ;---|*|
- ; \*/
- ;
- flushit proc near
- mov ax,1 ; reg 1
- call fmout
-
- inc ax ; reg 2
- call fmout
-
- inc ax ; reg 3
- call fmout
-
- inc ax ; reg 4
- call fmout
-
- mov al,8 ; reg 8
- call fmout
-
- mov al,20h ; flush all others from reg 20 to reg FF
- mov cx,0FFh-20h
- ;
- @@:
- call fmout
- inc ax
- loop @B
-
- ret
-
- flushit endp
-
- ;
- ; /*\
- ;---|*|---===< FMsplit >====----
- ;---|*|
- ;---|*| Split or combine the FM sides.
- ;---|*|
- ;---|*| Entry Conditions:
- ;---|*| AL = 1 for stereo, 0 for mono
- ;---|*|
- ;---|*| Exit Conditions:
- ;---|*| AX,BX,CX,DX modified
- ;---|*|
- ; \*/
- ;
- FMsplit proc near
- ;
- ; record either MONO or STEREO in the state table
- ;
- push es
- push di
- les di,[mvhwShadowPointer] ; we have to record in in the state
- ;
- ; maintain the split state fact in the old split FM bit
- ;
- mov ah,al ; save an original copy
- cmp al,1 ; set carry if zero
- sbb al,al ; al = FF for mono
- and al,bMImonofm ; keep the bit if mono
-
- and es:[di._audiomixr],NOT bMImonofm ; flush the bit
- or es:[di._audiomixr],al ; maybe set it
- mov al,es:[di._audiomixr] ; load a copy for old pas
-
- pop di
- pop es
- ;
- ; if OPL3, go do it's split, else just write out the new mixer setting
- ;
- test [_MVHWVersionBits],bMVOPL3 ; defaults are setup for 3812
- jnz splitopl3 ; which are okay, exit out now...
-
- mov dx,AUDIOMIXR ; get the mixer address
- xor dx,[_MVTranslateCode] ; translate to the board address
- out dx,al ; send the bits out to the h/w
-
- ret
- ;
- splitopl3:
- mov al,5 ; send it to the right FM reg 5
- mov dx,RFMADDR
- xor dx,[_MVTranslateCode] ; translate to the board address
- out dx,al ; send the index
-
- mov cx,[indexwrite]
- ;
- @@:
- in al,dx ; wait the prescribed period
- loop @B
-
- inc dx
- mov al,ah
- out dx,al ; send the data byte
-
- mov cx,[datawrite]
- ;
- @@:
- in al,dx ; wait the prescribed period
- loop @B
-
- ret
-
- FMsplit endp
-
- ;
- ; /*\
- ;---|*|---===< fmout >====----
- ;---|*|
- ;---|*| write to one of the chips.
- ;---|*|
- ;---|*| Entry Conditions:
- ;---|*| DX holds the base address (left side or right side)
- ;---|*| AL holds the index register value
- ;---|*| AH holds the data register value
- ;---|*|
- ;---|*| Exit Conditions:
- ;---|*| no registers modified
- ;---|*|
- ; \*/
- ;
- fmout proc near
- push ax
- push cx
-
- out dx,al
- mov cx,[indexwrite]
- ;
- @@:
- in al,dx
- loop @B
-
- xchg ah,al
- inc dx
- out dx,al
-
- mov cx,[datawrite]
- ;
- @@:
- in al,dx
- loop @B
-
- dec dx
-
- pop cx
- pop ax
- ret
-
- fmout endp
-
- end
-
-